#ifndef ARBOL_BINARIO
#define ARBOL_BINARIO


#define _NYT 256
#define _EOF 257

#include "NodoArbolHuffman.h"
#include "ListaDeNodosOrdenados.h"
#include "BitHandlerInput.h"
#include "BitHandlerOutput.h"
class ArbolHuffman {

private:
	NodoArbolHuffman* raiz;
	NodoArbolHuffman* nyt; // Nodo Not Yet Transmitted
	NodoArbolHuffman* nodoEof;
	ListaDeNodosOrdenados* nodosOrdenados; // Nodos ordenados por frecuencia en orden decendente
	BitHandlerInput* punteroHandlerInput;
	BitHandlerOutput* punteroHandlerOutput;
	string cadena;
	// Agrega un nuevo caracter al arbol. Deja el arbol valido (Sibling property)
	void agregarCaracter(unsigned int caracter);
	// Actualiza el árbol a partir de un nodo al que hay que incrementarle su frecuencia
	// Deja el arbol en un estado valido (Sibling property)
	void actualizar(NodoArbolHuffman* nodo);
	// Actualiza el árbol a partir del caracter NYT
	// Deja el arbol en un estado valido (Sibling property)
	void actualizarCaracterNuevo(unsigned int caracter);
	// Intercambia dos nodos de igual frecuencia
	void intercambiarNodos(NodoArbolHuffman* nodo, NodoArbolHuffman* nodoMaximo);
	// Recorre el arbol desde la raiz hasta el nodo y manda el código (al reves).
	void enviarCodigo(NodoArbolHuffman* nodo);
public:
	ArbolHuffman();
	~ArbolHuffman();
	ArbolHuffman(string cadena);
	void emitirEOF();

	// Recibe un caracter y emite su código. Actualiza el arbol
	unsigned int codificarCaracter(unsigned int caracter);
	unsigned char decodificarCaracter();
	void setBitHandlerOutput(BitHandlerOutput &bho);
	void setBitHandlerInput(BitHandlerInput &bhi);

};

#endif
